package com.querie.controller;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.StringTokenizer;

import com.mongodb.BasicDBObject;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.MongoClient;
import com.querie.config.Configuration;

public class ModelOutputController {

	static int numberOfFolds = Configuration.getNumOfFolds();

	
	
	public static void buildModelOutput() {

		Thread buildOutput[] = new Thread[numberOfFolds];
		
		//Build model from MF.dat into database (sessionid->{vector of fragment id's importance})
		for (int index = 1; index  <= numberOfFolds; index++)
		{
			buildOutput[index - 1] = new BuildOutputThread(index);
			buildOutput[index - 1].start();
		}
		
		for (int index2=0; index2 < numberOfFolds; index2++)
		{
			try {
				buildOutput[index2].join();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
//		buildOutput[0] = new BuildOutputThread(1);
//		buildOutput[0].start();
//		try {
//			buildOutput[0].join();
//		} catch (InterruptedException e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		}
	}
	
}

class BuildOutputThread extends Thread
{
	MongoClient mongo;
	DB database;
	DBCollection table; 
	int indexOfFold = 0;
	BuildOutputThread(int indexOfFold)
	{
		try {
			mongo = new MongoClient( "localhost" , 27017 );
			
		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		this.indexOfFold = indexOfFold;
		database = mongo.getDB("mffold"+indexOfFold);
		database.getCollection("mfmodel").drop();
		table = database.getCollection("mfmodel");
	}
	public void run()
	{
		String inputTestDir = Configuration.getTestInputDir();
		String line = new String();
		long sessionid = 0l;
		long fragmentid = 0l;
		double rating = 0.0;
		long oldSessionId = 0l;
		HashMap<String, Double> fragmentMap  = new HashMap<String, Double>();
		BasicDBObject document = new BasicDBObject();
		try {
			BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(new File(inputTestDir+"/fold"+indexOfFold+"/mf.dat"))));
			
			while((line = br.readLine())!=null)
			{
//				System.out.println("Processing ratings : "+line + "Thread : "+indexOfFold);
				StringTokenizer strToken = new StringTokenizer(line, ",");
				if (strToken.countTokens() < 3)
				{
					continue;
				}
				String sessionStr =  strToken.nextToken();
				String fragmentStr = strToken.nextToken();
				String ratingStr = strToken.nextToken();
				try
				{
					sessionid = Long.parseLong(sessionStr);
					fragmentid = Long.parseLong(fragmentStr);
					rating = Double.parseDouble(ratingStr);
				}
				catch(Exception e)
				{
					System.out.println("************************************************");
					e.printStackTrace();
					System.out.println(sessionStr);
					System.out.println(fragmentStr);
					System.out.println(ratingStr);
					System.out.println("************************************************");
					
					continue;
				}

				if (sessionid != oldSessionId && oldSessionId!=0)
				{
					// This is mark of new document
					// so persist the old list with session id as a document to the datbase and collections.
					document.put("sessionid", oldSessionId);
					document.put("fragments", fragmentMap);
					table.insert(document);
					document = new BasicDBObject();
					fragmentMap = new HashMap<String, Double>();
				}
				else
				{
					// maintain and append the list of fragments.
					fragmentMap.put(String.valueOf(fragmentid) , rating);
				}
				oldSessionId = sessionid;
			}
			br.close();
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		
	}
}